﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
using Common.ModelConvert;

namespace Common.HttpRequest
{
    /// <summary>
    /// Http请求帮助类
    /// </summary>
    public class HttpRequestUtils
    {
        /// <summary>
        /// Http请求方法
        /// </summary>
        public enum HttpRequestMethodType
        {
            Get = 1,   //Get方法
            Post = 2   //Post方法
        }

        public class HttpRequestContentType
        {
            public const string ApplicationJson = "application/json; charset=UTF-8";                                 //Json数据格式
            public const string ApplicationXWwwFormUrlencoded = "application/x-www-form-urlencoded; charset=UTF-8";  //表单的默认数据提交方式

        }

        /// <summary>
        /// 请求WebApi接口数据
        /// </summary>
        /// <param name="url">url地址</param>
        /// <param name="parameter">参数</param>
        /// <param name="methodType">请求方法</param>
        /// <returns></returns>
        public static string RequestWebApiData(string url, object parameter, HttpRequestMethodType methodType)
        {
            var dic = ConvertUtils.ObjectToDictionary(parameter);
            return RequestWebApiData(url, dic, false, null, 0, methodType);
        }


        /// <summary>
        /// 请求WebApi接口数据
        /// </summary>
        /// <typeparam name="T">返回类型</typeparam>
        /// <param name="url">url地址</param>
        /// <param name="parameter">参数</param>
        /// <param name="isOpenProxy">是否开启代理</param>
        /// <param name="proxyIp">代理服务器ip地址</param>
        /// <param name="proxyPort">代理服务器端口号</param>
        /// <param name="methodType">请求方法</param>
        /// <returns></returns>
        public static T RequestWebApiData<T>(string url, object parameter, bool isOpenProxy, string proxyIp, int proxyPort, HttpRequestMethodType methodType)
        {
            var resultStr = RequestWebApiData(url, parameter, isOpenProxy, proxyIp, proxyPort, methodType);
            return JsonUtils.ConvertJsonToObject<T>(resultStr);
        }

        /// <summary>
        /// 请求WebApi接口数据
        /// </summary>
        /// <param name="url">url地址</param>
        /// <param name="parameter">参数</param>
        /// <param name="isOpenProxy">是否开启代理</param>
        /// <param name="proxyIp">代理服务器ip地址</param>
        /// <param name="proxyPort">代理服务器端口号</param>
        /// <param name="methodType">请求方法</param>
        /// <returns></returns>
        public static string RequestWebApiData(string url, object parameter, bool isOpenProxy, string proxyIp, int proxyPort, HttpRequestMethodType methodType)
        {
            var dic = ConvertUtils.ObjectToDictionary(parameter);
            return RequestWebApiData(url, dic, isOpenProxy, proxyIp, proxyPort, methodType);
        }



        /// <summary>
        /// 请求WebApi接口数据
        /// </summary>
        /// <param name="url">url地址</param>
        /// <param name="parameter">参数</param>
        /// <param name="isOpenProxy">是否开启代理</param>
        /// <param name="proxyIp">代理服务器ip地址</param>
        /// <param name="proxyPort">代理服务器端口号</param>
        /// <param name="methodType">请求方法</param>
        /// <returns></returns>
        public static string RequestWebApiData(string url, Dictionary<string, object> parameter, bool isOpenProxy, string proxyIp, int proxyPort, HttpRequestMethodType methodType)
        {
            HttpWebRequest request = null;
            var paramBuilder = new StringBuilder();

            if (parameter != null)
            {
                foreach (var (key, value) in parameter)
                {
                    paramBuilder.Append($"&{key}={value}");  //拼接请求参数
                }
            }

            //https 请求
            if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase))
            {
                if (methodType == HttpRequestMethodType.Get && parameter != null && parameter.Count != 0)
                {
                    url = url + "?" + paramBuilder.ToString().TrimStart('&');
                }

                request = (HttpWebRequest)WebRequest.Create(url);
                request.ProtocolVersion = HttpVersion.Version10;
                ServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, errors) => true;  //总是接受
            }

            //http 请求
            else
            {
                if (methodType == HttpRequestMethodType.Get && parameter != null && parameter.Count != 0)
                {
                    url = url + "?" + paramBuilder.ToString().TrimStart('&');
                }

                request = (HttpWebRequest)WebRequest.Create(url);
            }

            //判断是否需要设置代理
            if (isOpenProxy)
            {
                request.Proxy = new WebProxy(proxyIp, proxyPort);
            }

            request.Method = methodType.ToString().ToUpper();
            request.ContentType = HttpRequestContentType.ApplicationJson;

            if (methodType == HttpRequestMethodType.Post && parameter != null && parameter.Count != 0)
            {
                //var buffer = Encoding.UTF8.GetBytes(paramBuilder.ToString().TrimStart('&'));
                var paramJson = JsonUtils.ConvertObjectToJson(parameter);
                var buffer = Encoding.UTF8.GetBytes(paramJson);
                request.ContentLength = buffer.Length;
                using var reqStream = request.GetRequestStream();
                reqStream.Write(buffer, 0, buffer.Length);
            }

            //获取响应内容
            using var stream = ((HttpWebResponse)request.GetResponse()).GetResponseStream();
            using var reader = new StreamReader(stream ?? throw new InvalidOperationException(), Encoding.UTF8);
            return reader.ReadToEnd();
        }

    }
}
